package com.JFapp.service.impl;

import com.JFapp.constants.SystemConstants;
import com.JFapp.domain.dto.ChangeRepairStatusDto;
import com.JFapp.domain.entity.Repair;
import com.JFapp.domain.entity.ResponseResult;
import com.JFapp.domain.entity.User;
import com.JFapp.domain.vo.PageVo;
import com.JFapp.domain.vo.RepairVo;
import com.JFapp.eumns.AppHttpCodeEnum;
import com.JFapp.exception.SystemException;
import com.JFapp.mapper.RepairMapper;
import com.JFapp.service.RepairService;
import com.JFapp.service.UserService;
import com.JFapp.utils.BeanCopyUtils;
import com.JFapp.utils.SecurityUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.swagger.annotations.ApiOperation;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
/**
 * 订单管理(Repair)表服务实现类
 *
 * @author makejava
 * @since 2023-12-28 17:28:23
 */
@Service("repairService")
public class RepairServiceImpl extends ServiceImpl<RepairMapper,Repair> implements RepairService {

    @Autowired
    private UserService userService;
    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Override
    public ResponseResult addRepair(Repair repair) {

        Long userId = SecurityUtils.getUserId();
        String phone = userService.selectPhone(userId);

        save(repair);

        RepairVo repairVo = BeanCopyUtils.copyBean(repair, RepairVo.class);
        repairVo.setPhoneNum(phone);
        //发送订单新增通知
        try {
            rabbitTemplate.convertAndSend("repairExchange","repair.add",repair);
        } catch (AmqpException e) {
            throw new SystemException(AppHttpCodeEnum.REPAIR_INFORM);
        }
        return ResponseResult.okResult(repairVo);
    }

    public ResponseResult informNew(Repair repair){

        return ResponseResult.okResult(repair);
    }

    @Override
    public ResponseResult getRepairing(Integer pageNum, Integer pageSize) {
        Long userId = SecurityUtils.getUserId();
        User user = userService.getById(userId);
        LambdaQueryWrapper<Repair> queryWrapper=new LambdaQueryWrapper<>();
        LambdaQueryWrapper<Repair> wrapper = queryWrapper.select().eq(Repair::getReceiver, user.getUserName()).eq(Repair::getStatus, SystemConstants.REPAIRING);
        Page page =new Page<>(pageNum,pageSize);
        page(page,wrapper);
        List<Repair> repairList = page.getRecords();
        List<RepairVo> repairVo = BeanCopyUtils.copyBeanList(repairList, RepairVo.class);
        PageVo pageVo =new PageVo(repairVo,page.getTotal());
        return ResponseResult.okResult(pageVo);
    }

    @Override
    public ResponseResult getDetailById(Long repairId) {
        Repair repair = getById(repairId);
        RepairVo repairVo = BeanCopyUtils.copyBean(repair, RepairVo.class);
        repairVo.setPhoneNum(userService.selectPhone(SecurityUtils.getUserId()));
        if (userService.selectID(repair.getReceiver())!=null){
            String phone = userService.selectPhone(userService.selectID(repair.getReceiver()));
            repairVo.setReceiverPhoneNum(phone);
        }
        return ResponseResult.okResult(repairVo);
    }

    @Override
    @ApiOperation("查询个人订单")
    public ResponseResult<RepairVo> selectRepairByCreatId(Integer pageNum, Integer pageSize) {
        Long userId = SecurityUtils.getUserId();
        LambdaQueryWrapper<Repair> wrapper=new LambdaQueryWrapper<>();
        LambdaQueryWrapper<Repair> eq = wrapper.select().eq(Repair::getCreateId, userId).orderByAsc(Repair::getStatus).orderByDesc(Repair::getCreateTime);
        return getRepairVoResponseResult(pageNum, pageSize, eq);
    }

    @Override
    @ApiOperation("查询所有未接订单")
    public ResponseResult<RepairVo> selectRepair(Integer pageNum, Integer pageSize) {
        LambdaQueryWrapper<Repair> wrapper=new LambdaQueryWrapper<>();
        LambdaQueryWrapper<Repair> queryWrapper = wrapper.select().eq(Repair::getStatus,SystemConstants.WILL_REPAIR);
        return getRepairVoResponseResult(pageNum, pageSize, queryWrapper);
    }


    @Override
    public ResponseResult completeRepair(Integer pageNum, Integer pageSize) {
        Long userId = SecurityUtils.getUserId();
        User user = userService.getById(userId);
        LambdaQueryWrapper<Repair> wrapper=new LambdaQueryWrapper<>();
        LambdaQueryWrapper<Repair> queryWrapper = wrapper.select()
                                                        .eq(Repair::getReceiver,user.getUserName())
                                                        .eq(Repair::getStatus, SystemConstants.REPAIRED);
        return getRepairVoResponseResult(pageNum,pageSize,queryWrapper);
    }



    private ResponseResult getRepairVoResponseResult(Integer pageNum, Integer pageSize, LambdaQueryWrapper<Repair> queryWrapper) {
        Page<Repair> repairPage =new Page<>(pageNum,pageSize);
        page(repairPage,queryWrapper);
        List<Repair> records = repairPage.getRecords();
        List<RepairVo> repairVos = BeanCopyUtils.copyBeanList(records, RepairVo.class);
        PageVo pageVo = new PageVo(repairVos, repairPage.getTotal());
        return ResponseResult.okResult(pageVo);
    }

    @Override
    //TODO 缺通知1
    public ResponseResult receptionRepair(ChangeRepairStatusDto changeRepairStatusDto) {
        Repair repair = baseMapper.selectById(changeRepairStatusDto.getRepairId());
        if(repair.getRepairId()!=null&&repair.getStatus()== SystemConstants.WILL_REPAIR&&changeRepairStatusDto.getStatus()!=null){
            changeStatus(repair,changeRepairStatusDto.getStatus());
            return ResponseResult.okResult();
        } else if (repair.getRepairId()!=null&&repair.getStatus()== SystemConstants.REPAIRING&&changeRepairStatusDto.getStatus()!=null) {
            changeStatus(repair,changeRepairStatusDto.getStatus());
            return ResponseResult.okResult();
        } else {
            return ResponseResult.errorResult(AppHttpCodeEnum.NOT_FIND_REPAIR);
        }
    }
    private void changeStatus(Repair repair, Integer status) {
        Long userId = SecurityUtils.getUserId();
        User user = userService.getBaseMapper().selectById(userId);
        repair.setStatus(status);
        repair.setReceiver(user.getUserName());
        updateById(repair);
    }

    //TODO 缺通知2
    @ApiOperation("根据id修改订单内容")
    @Override
    public ResponseResult updateRepairById(Repair repair) {
        Long userId = SecurityUtils.getUserId();
        if(userId!=repair.getCreateId()){
            throw new RuntimeException(AppHttpCodeEnum.NO_OPERATOR_AUTH.getMessage());
        }
        LambdaUpdateWrapper<Repair> repairLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        LambdaUpdateWrapper<Repair> wrapper = repairLambdaUpdateWrapper.eq(Repair::getRepairId, repair.getRepairId());
        update(repair,wrapper);

        return ResponseResult.okResult();
    }

    @Override
    @ApiOperation("取消订单")
    public ResponseResult cancelRepair(Repair repair) {
        Long userId = SecurityUtils.getUserId();
        if(userId!=repair.getCreateId()){
            throw new RuntimeException(AppHttpCodeEnum.NO_OPERATOR_AUTH.getMessage());
        }
        LambdaQueryWrapper<Repair> queryWrapper=new LambdaQueryWrapper<>();
        LambdaQueryWrapper<Repair> wrapper= queryWrapper.select()
                                                        .eq(Repair::getRepairId, repair.getRepairId())
                                                        .ne(Repair::getStatus,SystemConstants.REPAIRED);


        baseMapper.delete(wrapper);
        return ResponseResult.okResult();
    }

    @Override
    @Transactional(rollbackFor = {RuntimeException.class})
    @ApiOperation("完成订单")
    public ResponseResult complete(Repair repair) {
        Long userId = SecurityUtils.getUserId();
        LambdaUpdateWrapper<Repair> updateWrapper = new LambdaUpdateWrapper<>();
        LambdaUpdateWrapper<Repair> wrapper = updateWrapper.set(Repair::getStatus, SystemConstants.REPAIRED)
                .eq(Repair::getRepairId, repair.getRepairId())
                .eq(Repair::getCreateId, userId)
                .eq(Repair::getStatus, SystemConstants.REPAIRING);
        update(repair,wrapper);
        Repair repair1 = baseMapper.selectById(repair.getRepairId());
        //发送订单完成通知
        try {
            rabbitTemplate.convertAndSend("repairExchange","repair.finish",repair1);
        } catch (AmqpException e) {
            throw new SystemException(AppHttpCodeEnum.REPAIR_INFORM);
        }
        return ResponseResult.okResult();
    }

}
